#include "xcamera_widget.h"
#include "xcamera_config.h"
#include "xdecode_task.h"
#include "xdemux_task.h"
#include "xvideo_view.h"
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QListWidget>
#include <QPainter>
#include <QStyleOption>
XCameraWidget::XCameraWidget(QWidget *parent) : QWidget(parent) {
  this->setAcceptDrops(true);
}

XCameraWidget::~XCameraWidget() {
  if (demux_) {
    demux_->Stop();
    delete demux_;
    demux_ = nullptr;
  }
  if (decode_) {
    decode_->Stop();
    delete decode_;
    decode_ = nullptr;
  }
}

void XCameraWidget::paintEvent(QPaintEvent *ev) {
  //
  QStyleOption opt;
  opt.initFrom(this);
  QPainter p(this);
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
  QWidget::paintEvent(ev);
}

void XCameraWidget::dragEnterEvent(QDragEnterEvent *e) {
  e->acceptProposedAction();
}

void XCameraWidget::dropEvent(QDropEvent *e) {
  // 拿到
  auto cam_list = qobject_cast<QListWidget *>(e->source());
  int index = cam_list->currentRow();
  auto data = XCameraConfig::Instance()->GetCam(index);
  if (!Open(data.sub_url)) {
    return;
  }
}

bool XCameraWidget::Open(const char *url) {
  // 解封装
  if (demux_)
  {
      demux_->Stop();
  }

  if (decode_)
  {
      decode_->Stop();
  }
  if (!demux_)
    demux_ = new XDemuxTask();
  if (!demux_->Open(url)) {
    return false;
  }
  // 解码线程
  if (!decode_)
    decode_ = new XDecodeTask();
  auto para = demux_->CopyVideoPara();
  if (!decode_->Open(para->para)) {
    return false;
  }
  demux_->set_next(decode_);
  // 初始化渲染
  view_ = XVideoView::Create();
  view_->set_win_id((void *)this->winId());
  view_->Init(para->para);
  // 启动解封装和解码线程
  demux_->Start();
  decode_->Start();
  return true;
}

void XCameraWidget::Draw() {
  if (!demux_ || !decode_ || !view_) {
    return;
  }
  auto f = decode_->GetFrame();
  if (!f)
    return;
  view_->DrawFrame(f);
  XFreeFrame(&f);
}
